package jsoup;

import com.alibaba.fastjson.JSONArray;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.*;

/**
 * work：jre 1.8
 *
 * @author WEN轩
 *
 */
public class img_sjtx {
    /**
     * 下载图片到指定目录
     *
     * @param filePath 文件路径
     * @param imgUrl   图片URL
     */
    // ***********************自定义变量
    // 想要爬取的网址
    static String url = "";
    // 保存的位置
    static String place;
    // 文件链接所在标签
    static String biao;
    // 链接引入的方式//src url
    static String path;
    // 需要下载的文件的后缀数组
    static String[] types;
    // 将下载失败的文件记录下来
    static Set<String> error = new HashSet<String>();

    // 开始下载文件
    public static void downImages(String filePath, String imgUrl) {
        // 若指定文件夹没有，则先创建
        File dir = new File(filePath);
        String imgUrl_old = imgUrl;
        if (!dir.exists()) {// 目录不存在就创建
            dir.mkdirs();
        }
        // 截取图片文件名
        String fileName = imgUrl.substring(imgUrl.lastIndexOf('/') + 1, imgUrl.length());

        try {
            // 文件名里面可能有中文或者空格，所以这里要进行处理。但空格又会被URLEncoder转义为加号
            String urlTail = URLEncoder.encode(fileName, "UTF-8");
            // 因此要将加号转化为UTF-8格式的%20
            imgUrl = imgUrl.substring(0, imgUrl.lastIndexOf('/') + 1) + urlTail.replaceAll("\\+", "\\%20");

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // 写出的路径
        File file = new File(filePath + File.separator + fileName);
        if (file.exists()) {// 对已经下载过的文件跳过，不需要可以将if语句去掉
            System.out.println("已存在");
            return;
        }
        try {
            // 获取图片URL
            URL url = new URL(imgUrl);
            // 获得连接
            URLConnection connection = url.openConnection();
            // 设置10秒的相应时间
            connection.setConnectTimeout(10 * 1000);
            // 获得输入流
            InputStream in = connection.getInputStream();
            // 获得输出流
            BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
            // 构建缓冲区
            byte[] buf = new byte[1024];
            int size;
            // 写入到文件
            while (-1 != (size = in.read(buf))) {
                out.write(buf, 0, size);
            }
            out.close();
            in.close();
            System.out.println("下载完成");
        } catch (MalformedURLException e) {
            System.out.println("失败");
            error.add(imgUrl_old);
//			e.printStackTrace();
        } catch (IOException e) {
            System.out.println("失败");
//			e.printStackTrace();
            error.add(imgUrl_old);
        } catch (Exception e) {
            System.out.println("下载超时");
//			e.printStackTrace();
        }

    }

    // main
    public static void main(String[] args) {
//        Scanner sc = new Scanner(System.in);
//        System.out.println("*********Java 爬虫下载网页文件  wx0725.top");
//        System.out.println("请依次输入下面属性的值：(回车确认)");
//        System.out.print("1.Website you want to crawl(网址链接): ");
//        setUrl(sc.nextLine());
//        System.out.println(getUrl());
//        System.out.print("2.Save in local location(绝对路径): ");
//        setPlace(sc.nextLine());
//        System.out.println(getPlace());
//        System.out.print("3.Label of file link(标签): ");
//        setBiao(sc.nextLine());
//        System.out.println(getBiao());
//        System.out.print("4.The way of link introduction[src/href]: ");
//        setPath(sc.nextLine());
//        System.out.println(getPath());
//        System.out.print("5.File extension(后缀数组，空格分隔): ");
//        setTypes(sc.nextLine().split(" "));
//        System.out.println(getTypes());

        List<Map<String, Object>> datas = new ArrayList<>();

        for (int i = 1; i < 75; i++) {
            if (i == 1) {
                setUrl("https://www.samsph.com/expert");
            } else {
                setUrl("https://www.samsph.com/expert/" + i);
            }
            setPlace("C:\\Users\\17628\\Desktop\\图片");
            setBiao("img");
            setPath("src");
            setTypes(new String[]{"jpg"});
            datas.addAll(download());
        }



//        sc.close();


//        setUrl("https://www.samsph.com/expert");
//        setPlace("C:\\Users\\17628\\Desktop\\图片");
//        setBiao("img");
//        setPath("src");
//        setTypes(new String[]{"jpg"});
//        List<Map<String, Object>> download = download();
//        datas.addAll(download);

        //        写入数据到文件
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\17628\\Desktop\\医生数据1.txt"));
            for (Map<String, Object> data : datas) {
                bw.write(JSONArray.toJSONString(data));
                bw.newLine();
                bw.flush();
            }
            bw.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static List<Map<String, Object>> download() {
        List<Map<String, Object>> dataAll = new ArrayList<>();

        // 利用Jsoup获得连接
        Connection connect = Jsoup.connect(url);
        // 执行体
        try {
            System.out.println("请耐心等待......");
            // 得到Document对象
            Document document = connect.get();
            System.out.println("连接成功！！！");
            // 查找所有img标签
//            Elements imgs = document.getElementsByTag(biao);
            Elements ul = document.getElementsByClass("doctor-list clearfix");
            //获取到详情标签
            Elements lis = ul.get(0).children();
            //遍历所有li标签
            for (Element li : lis) {
                Element detail = li.child(0);
                Elements children = detail.children();//li标签下级三个标签
                //详情地址
                Element a = children.get(0);
                Element h2 = children.get(1);
                Element div = children.get(2);

                String detailUrl = a.attr("abs:href");
//                System.out.println("详情地址：" + detailUrl);

                String imageUrl = a.child(0).attr("abs:src");
                if (StringUtils.isBlank(imageUrl)) {
                    imageUrl = a.child(0).attr("abs:data-original");
                }
//                System.out.println("头像：" + imageUrl);

                String name = h2.child(0).text();
//                System.out.println("姓名：" + name);
                String dept = "";
                String position = "";
                String rank = "";
                for (Element message : div.children()) {
                    String text = message.text();
                    if (text.startsWith("科室：")) {
//                        System.out.println("科室：" + text);
                        dept = text.replaceAll("科室：", "");
                    }

                    if (text.startsWith("职称：")) {
//                        System.out.println("职称：" + text);
                        position = text.replaceAll("职称：", "");
                    }

                    if (text.startsWith("级别：")) {
//                        System.out.println("级别：" + text);
                        rank = text.replaceAll("级别：", "");
                    }
                }
                String beGood = li.child(1).text();
                beGood = beGood.replaceAll("擅长：", "");
//                System.out.println("擅长：" + beGood);
                //判断是否有详细链接
                Connection detailConnect = Jsoup.connect(detailUrl);
                Document detailDocument = detailConnect.get();
//                System.out.println("详情连接成功！！！");
                // 查找所有img标签
                Elements introduce = detailDocument.getElementsByClass("inner-list-content doctor-items-intro");
                Elements introduceDetails = introduce.get(0).children();
                List<String> introduceStr = new ArrayList<>();
                for (Element introduceDetail : introduceDetails) {
                    introduceStr.add(introduceDetail.text());
                }
//                System.out.println("介绍：" + JSONArray.toJSONString(introduceStr));
                //封装数据
                Map<String, Object> map = new HashMap<>();
                map.put("imageUrl", imageUrl.substring(imageUrl.lastIndexOf('/') + 1));
                map.put("name", name);
                map.put("dept", dept);
                map.put("position", position);
                map.put("rank", rank);

                map.put("beGood", beGood);
                map.put("introduceStr", introduceStr);

                dataAll.add(map);

            }
//            image(document);
        } catch (IOException e) {
            System.out.println("由于您的操作异于常人导致下载途中出现异常。(请重试)");
//			e.printStackTrace();
            System.out.println("r读取时间超时");
        }
        return dataAll;
    }

    private static void image(Document document) {
        Map<String, Boolean> v = new HashMap<String, Boolean>();// 存储需要下载的类型
        for (String ch : types) {
            v.put(ch, true);
        }
        Elements imgs = document.getElementsByClass("lazy");
        System.out.println("开始下载" + imgs.size());
        // 遍历img标签并获得src的属性
        for (Element element : imgs) {
            // 获取每个img标签URL "abs:"表示绝对路径
            String imgSrc = element.attr("abs:" + path);
            if (StringUtils.isBlank(imgSrc)) {
                imgSrc = element.attr("abs:data-original");
            }
            System.out.println(imgSrc);
            String type = imgSrc.substring(imgSrc.lastIndexOf(".") + 1).trim();// 获取链接的后缀类型

            System.out.println(type);
            if (v.containsKey(type)) {
                // 打印URL
                System.out.println("正在下载" + "来自" + imgSrc.substring(0, imgSrc.lastIndexOf("/") + 1) + "的" + imgSrc.substring(imgSrc.lastIndexOf("/") + 1));
                // 下载图片到本地
                img_sjtx.downImages(place, imgSrc);
            }
        }
        System.out.println("网页爬取完成");
        if (!error.isEmpty()) {// 判断是否有失败的文件
            System.out.println("下面是下载失败的文件，建议您手动下载。（小弟不才）");
            Iterator<String> it = error.iterator();
            it.forEachRemaining(obj -> System.out.println(obj));
        } else {
            System.out.println("********恭喜没有下载失败的文件*******");
        }
    }

    public static String getUrl() {
        return url;
    }

    public static void setUrl(String url) {
        img_sjtx.url = url;
    }

    public static String getPlace() {
        return place;
    }

    public static void setPlace(String place) {
        img_sjtx.place = place;
    }

    public static String getBiao() {
        return biao;
    }

    public static void setBiao(String biao) {
        img_sjtx.biao = biao;
    }

    public static String getPath() {
        return path;
    }

    public static void setPath(String path) {
        img_sjtx.path = path;
    }

    public static String[] getTypes() {
        return types;
    }

    public static void setTypes(String[] types) {
        img_sjtx.types = types;
    }

    public static Set<String> getError() {
        return error;
    }

    public static void setError(Set<String> error) {
        img_sjtx.error = error;
    }
}

